home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 22 / Cream of the Crop 22.iso / program / snip9611.zip / PR.C < prev    next >
C/C++ Source or Header  |  1996-11-24  |  9KB  |  275 lines

  1. /* +++Date last modified: 17-Nov-1996 */
  2.  
  3. /*
  4.       This program is similar to a program of the same name found on UNIX.
  5.       It prints the files named in the command tail with headings
  6.       except as modified below.
  7.  
  8.       usage: pr [-i -ln -on -pname -tn -wn] file1[ file2 ... filen]
  9.       where:      -i     = accept files from stdin
  10.                   -ln    = set lines per page to n
  11.                   -on    = set page offset to n
  12.                   -pname = output to file <name>
  13.                   -tn    = set tabs to n cols
  14.                   -wn    = set page width to n
  15.  
  16.       note: the expr 'PAGE(mesg)' found in col 1 will cause a formfeed
  17.                   and the 'mesg' to be included in the title line on this and
  18.                   each subsequent page until EOF or another PAGE.
  19. */
  20.  
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include <time.h>
  25. #include "getopts.h"                            /* Also in SNIPPETS     */
  26.  
  27. #define TAB_DEFAULT 4
  28. #define PAGE_LENGTH 60
  29. #define PAGE_OFFSET 0
  30. #define PAGE_WIDTH      80
  31. #define MAX_ARGS    70
  32. #define MAX_FILES 64
  33. #define PATH_LENGTH 63
  34. #define PAGE(head)
  35.  
  36.  
  37. int       page_length = PAGE_LENGTH;
  38. int       page_offset = PAGE_OFFSET;
  39. int       page_width  = PAGE_WIDTH;
  40. int       tab_width   = TAB_DEFAULT;
  41. Boolean_T read_stdin  = False_;
  42.  
  43. char      print_name[FILENAME_MAX] = "PRN";
  44. char      filenames[MAX_FILES] [FILENAME_MAX];
  45.  
  46. struct Option_Tag options[] = {
  47.       {'I',  False_, Boolean_Tag, &read_stdin  , NULL, NULL, NULL},
  48.       {'L',  False_, Word_Tag,    &page_length , NULL, NULL, NULL},
  49.       {'O',  False_, Word_Tag,    &page_offset , NULL, NULL, NULL},
  50.       {'T',  False_, Word_Tag,    &tab_width   , NULL, NULL, NULL},
  51.       {'W',  False_, Word_Tag,    &page_width  , NULL, NULL, NULL},
  52.       {'P',  False_, String_Tag,   print_name  , NULL, NULL, NULL},
  53.       {'\0', False_, Error_Tag,    NULL        , NULL, NULL, NULL}
  54. };
  55.  
  56. char title[80];
  57. char Date[20];
  58. char Time[20];
  59. int  ln, pn;
  60.  
  61. void prt (char fnp[], FILE *lp);
  62. void new_page (char *fnp, FILE *lp);
  63. void indent(FILE *lp);
  64.  
  65. PAGE (MAIN)
  66. main(int argc, char *argv[])  /* copy file to printer */
  67. {
  68.       FILE *lp;
  69.       int fi;
  70.       int pn;
  71.       char *cp;
  72.  
  73.       if (argc < 2) /* No args so tell 'em how it works */
  74.       {
  75.             fprintf(stderr,
  76.             "usage:\n\npr %s %s\n\n",
  77.             "[-i] [-lnn] [-onn] [-p<name>] [-tn] [-wnn]",
  78.             "[file1[ file2 ... filen]]");
  79.             fprintf(stderr,
  80.             "where: i = read 'stdin' for filenames to print\n");
  81.             fprintf(stderr,
  82.             "       l = lines-per-page and nn <= 120\n");
  83.             fprintf(stderr,
  84.             "       o = page offset    and nn <= 120\n");
  85.             fprintf(stderr,
  86.             "       p = print redirection and\n");
  87.             fprintf(stderr,
  88.             "           <name> = pathname or devicename\n");
  89.             fprintf(stderr,
  90.             "       t = spaces-per-tab and n  <= 8\n");
  91.             fprintf(stderr,
  92.             "       w = page width     and nn <= 160\n\n");
  93.             fprintf(stderr,
  94.             "Notes: PAGE(<title text of any length>) in col 1 of text file\n");
  95.             fprintf(stderr,
  96.             "       and <title text...> the title you want.\n\n");
  97.             fprintf(stderr,
  98.             "       C pgms should include the following macro:\n\n");
  99.             fprintf(stderr,
  100.             "            #define PAGE(title)\n\n");
  101.             fprintf(stderr,
  102.             "       < and > not required and should not be used\n\n");
  103.             exit(0);
  104.       }
  105.       
  106.       if (Error_ == getopts(argc, argv))
  107.             return 1;
  108.       
  109.       if ((page_length <= 0) || (page_length > 120))
  110.             page_length = PAGE_LENGTH;
  111.  
  112.       if ((tab_width <= 0) || (tab_width > 8))
  113.             tab_width = TAB_DEFAULT;
  114.  
  115.       if ((page_offset < 0) || (page_offset > 120))
  116.             page_offset = PAGE_OFFSET;
  117.  
  118.       if ((page_width <= 0) || (page_width > 160))
  119.             page_width = PAGE_WIDTH;
  120.  
  121.       for (fi = 0, pn = 1; pn < xargc; ++fi, ++pn)
  122.       {
  123.             if (fi < MAX_FILES)
  124.                   strcpy(filenames[fi], xargv[pn]);
  125.             else
  126.             {
  127.                   fprintf(stderr, "pr: "
  128.                         "Exceeded maximum file capacity\n");
  129.                   break;
  130.             }
  131.       }
  132.  
  133.       if ((lp = fopen(print_name, "w")) == 0)
  134.       {
  135.             fprintf(stderr, "pr: Unable to open %s as output\n", print_name);
  136.             exit(1);
  137.       }
  138.  
  139.       if (read_stdin)
  140.       {
  141.             for(;;)
  142.             {
  143.                   if (fi == MAX_FILES)
  144.                   {
  145.                         fputs("pr: Exceeded maximum file capacity\n",
  146.                               stderr);
  147.                         break;
  148.                   }
  149.                   cp = fgets(filenames [fi], FILENAME_MAX, stdin);
  150.                   if (!cp)
  151.                         break;
  152.                   else  fi++;
  153.             }
  154.       }
  155.       /* now print each file */
  156.  
  157.       for (pn = 0; pn < fi; pn++)
  158.             prt(filenames [pn], lp);  /* print the file */
  159.       return 0;
  160. }
  161. PAGE (NEW PAGE)
  162.  
  163. void new_page (char *fnp, FILE *lp)
  164. {
  165.       if (ln < 3)
  166.             return;
  167.       ++pn;
  168.       if (pn > 1)
  169.             fputc('\f', lp);
  170.       fprintf(lp, "%s    %s %s    PAGE %d:  %s\n\n",
  171.                    fnp, Date, Time, pn, title);
  172.       ln = 2;
  173. }
  174.  
  175. PAGE (PRINT FILE)
  176. void prt (char fnp[], FILE *lp)
  177. {
  178.       FILE *inp_file;
  179.       int col;
  180.       char line [256], *st, *et, *sp;
  181.       time_t now;
  182.       struct tm *tnow;
  183.  
  184.       inp_file = fopen(fnp, "r");
  185.       if (!inp_file)
  186.       {
  187.             fprintf(stderr, "pr: unable to open %s\n", fnp);
  188.             return;
  189.       }
  190.       else
  191.             fprintf(stderr, "pr: printing %s\n", fnp);
  192.  
  193.       pn = 0;
  194.       ln = 999;
  195.       now  = time(&now);
  196.       tnow = localtime(&now);
  197.       strftime(Date, 19, "%a %d %b %Y", tnow);
  198.       strftime(Time, 19, "%I:%M %PM", tnow);
  199.       *title = '\0';
  200.  
  201.       while (fgets(line, 256, inp_file))
  202.       {
  203.             if (strncmp(line, "PAGE", 4) == 0)
  204.             {
  205.                   if (NULL != (st = strchr(line, '(')))
  206.                   {
  207.                         et = strchr(line, ')');
  208.                         strncpy(title, st + 1, (et) ? et - st - 1 : 160);
  209.                   }
  210.                   ln = 999;
  211.             }
  212.  
  213.             if (ln > page_length)
  214.                   new_page(fnp, lp);
  215.  
  216.             if (page_offset)
  217.                   indent(lp);
  218.  
  219.             for (col = (page_offset) ? page_offset : 1, sp = &line[0];
  220.                    *sp; sp++)
  221.             {
  222.                   switch (*sp)
  223.                   {
  224.                   case '\t':  /* tab character */
  225.                         do
  226.                         {
  227.                               fputc(' ', lp);
  228.                               col++;
  229.                               if (col > page_width)
  230.                               {
  231.                                     fputc('\n', lp);
  232.                                     col = (page_offset) ? page_offset : 1;
  233.                                     ln++;
  234.                                     if (ln > page_length)
  235.                                           new_page(fnp, lp);
  236.                                     if (page_offset)
  237.                                           indent(lp);
  238.                                     break;
  239.                               }
  240.                         } while ((col - 1) % tab_width);
  241.                         break;
  242.  
  243.                   case '\f':  /* form feed character */
  244.                         new_page(fnp, lp);
  245.                         break;
  246.  
  247.                   default:
  248.                         fputc(*sp, lp);
  249.                         ++col;
  250.                         if (col > page_width)
  251.                         {
  252.                               fputc('\n', lp);
  253.                               col = (page_offset) ? page_offset - 1 : 0;
  254.                               ln++;
  255.                               if (ln > page_length)
  256.                                     new_page(fnp, lp);
  257.                               if (page_offset)
  258.                                     indent(lp);
  259.                         }
  260.                   }
  261.             } /* of line print (for) */
  262.             ++ln;
  263.       } /* of while not eof */
  264.       fclose(inp_file);
  265.       fputc(014, lp);
  266. } /* of print */
  267.  
  268. void indent(FILE *lp)
  269. {
  270.       int i;
  271.  
  272.       for(i = 1; i < page_offset; i++)
  273.             fputc(' ', lp);
  274. }
  275.